package com.cmonbaby.adapter.recycleview.wrapper;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;

import com.cmonbaby.adapter.recycleview.RViewHolder;
import com.cmonbaby.adapter.recycleview.utils.WrapperUtils;

/**
 * RecycleView底部上拉加载更多包装类
 * @author simon 2016-9-19 下午16:05:29
 * @since JDK1.8 SDK6.0.1
 * @version V2.3.4
 */
public class LoadMoreWrapper extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int ITEM_TYPE_LOAD_MORE = Integer.MAX_VALUE - 2;
    private RecyclerView.Adapter mInnerAdapter;
    private View mLoadMoreView; // 加载更多布局
    private int mLoadMoreLayoutId; // 加载更多布局ID
    private int oldPosition; // 记录上次适配器集合数量
    private int rowsPageNumber; // 最后一页少于多少条数据显示无更多数据
    private boolean onlyOnePage; // 仅仅只有一页且全部显示完
    private boolean isNotify; // 是否通知过一次没有更多数据

    /**
     * 构造方法，传入RecyclerView.Adapter
     *
     * @param adapter RecyclerView.Adapter
     * @param rowsPageNumber 最后一页少于多少条数据显示无更多数据
     */
    public LoadMoreWrapper(RecyclerView.Adapter adapter, int rowsPageNumber) {
        mInnerAdapter = adapter;
        this.rowsPageNumber = rowsPageNumber;
    }

    /** 是否有加载更多布局，根据判断布局是否不为空 */
    private boolean hasLoadMore() {
        return mLoadMoreView != null || mLoadMoreLayoutId != 0;
    }

    /** 是否没有更多数据，少于noMoreDataNumber显示无更多数据 */
    private boolean isNoMoreData() {
        if (mInnerAdapter.getItemCount() < rowsPageNumber) { // 只有一页且全部显示完时，隐藏布局
            onlyOnePage = true;
            return true;
        }
        if (oldPosition != 0 && mInnerAdapter.getItemCount() - oldPosition < rowsPageNumber) {
            oldPosition = mInnerAdapter.getItemCount();
            return true;
        } else {
            oldPosition = mInnerAdapter.getItemCount();
            return false;
        }
    }

    /**
     * 是否展示加载更多，hasLoadMore()判断与条目位置大于等于条目总数
     *
     * @param position 条目位置
     * @return true则为是
     */
    private boolean isShowLoadMore(int position) {
        return hasLoadMore() && (position >= mInnerAdapter.getItemCount());
    }

    /** 根据数据源的position返回需要显示的的layout的type，type的值必须从0开始 */
    @Override
    public int getItemViewType(int position) {
        if (isShowLoadMore(position)) {
            return ITEM_TYPE_LOAD_MORE;
        }
        return mInnerAdapter.getItemViewType(position);
    }

    /** 为Item创建视图 */
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == ITEM_TYPE_LOAD_MORE) {
            RViewHolder holder;
            // 获得RecycleViewViewHolder对象，其中使用构造方法实现
            if (mLoadMoreView != null) {
                holder = RViewHolder.createViewHolder(parent.getContext(), mLoadMoreView);
            } else {
                holder = RViewHolder.createViewHolder(parent.getContext(), parent, mLoadMoreLayoutId);
            }
            return holder;
        }
        // 如果都不符合条件，则正常显示
        return mInnerAdapter.onCreateViewHolder(parent, viewType);
    }

    /** 将数据绑定到Item的视图上 */
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
         if (isShowLoadMore(position)) {
             if (isNoMoreData()) {
                 // 条件一：只有一页且全部显示完时不提示，条件二：滑到最底部提示过一次，后续不再提示
                 if (mOnLoadMoreListener != null && !onlyOnePage && !isNotify) {
                     isNotify = true;
                     mOnLoadMoreListener.onNoMoreData();
                 }
                 ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
                 layoutParams.height = 0;
                 holder.itemView.setLayoutParams(layoutParams);
                 holder.itemView.setVisibility(View.GONE);
                 return;
             }
            if (mOnLoadMoreListener != null && !onlyOnePage) mOnLoadMoreListener.onLoadMoreRequested();
            return;
        }
        mInnerAdapter.onBindViewHolder(holder, position);
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, (layoutManager, oldLookup, position) -> {
            if (isShowLoadMore(position)) {
                return layoutManager.getSpanCount();
            }
            if (oldLookup != null) {
                return oldLookup.getSpanSize(position);
            }
            return 1;
        });
    }

    @Override
    public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
        mInnerAdapter.onViewAttachedToWindow(holder);

        if (isShowLoadMore(holder.getLayoutPosition())) {
            WrapperUtils.setFullSpan(holder);
        }
    }

    /** 绘制RecycleView之前，将会先调用getItemCount方法来获取Item的个数 */
    @Override
    public int getItemCount() {
        return mInnerAdapter.getItemCount() + (hasLoadMore() ? 1 : 0);
    }

    /** 加载更多监听器 */
    public interface OnLoadMoreListener {

        /** 请求加载更多 */
        void onLoadMoreRequested();

        /** 没有更多数据 */
        void onNoMoreData();
    }

    private OnLoadMoreListener mOnLoadMoreListener;

    /**
     * 设置加载更多监听
     * @param loadMoreListener 需要实现传入
     * @return LoadMoreWrapper
     */
    public LoadMoreWrapper setOnLoadMoreListener(OnLoadMoreListener loadMoreListener) {
        if (loadMoreListener != null) {
            mOnLoadMoreListener = loadMoreListener;
        }
        return this;
    }

    /**
     * 设置加载更多布局View
     *
     * @param loadMoreView 加载更多布局View
     */
    public LoadMoreWrapper setLoadMoreView(View loadMoreView) {
        mLoadMoreView = loadMoreView;
        return this;
    }

    /**
     * 设置加载更多布局View
     *
     * @param layoutId 加载更多布局ViewID
     */
    public LoadMoreWrapper setLoadMoreView(int layoutId) {
        mLoadMoreLayoutId = layoutId;
        return this;
    }

}
